#pragma once
#include <imgui/imgui.h>
#include <optional>
#include <vector>
namespace ciallo {

enum class Format {
    RGBA,
    RGB,
};
class Texture {
  private:
    unsigned int _id{0};
    int _width{0};
    int _height{0};
    int _channels{0};
    bool _is_dirty{false};
    std::vector<unsigned char> _data;
    Format _format;

  public:
    Texture() = default;
    Texture(int width, int height, Format format);

    Texture(const Texture &) = delete;
    Texture &operator=(const Texture &) = delete;

    Texture(Texture &&rhs) { *this = std::move(rhs); }
    Texture &operator=(Texture &&rhs) {
        if (this != &rhs) {

            _id = rhs._id;
            _width = rhs._width;
            _height = rhs._height;
            _channels = rhs._channels;
            _format = rhs._format;
            rhs._id = 0;
        }
        return *this;
    }

    ~Texture();
    static std::optional<Texture> load(const char *path);

    void update(const unsigned char *data, int width, int height) {
        assert(_id != 0);
        assert(width == _width && height == _height);
        _data.assign(data, data + width * height * _channels);

        _is_dirty = true;
    }
    int get_width() { return _width; }
    int get_height() { return _height; }
    ImTextureID get_handle() {
        if (_is_dirty) {
            printf("Updating texture\n");
            update_texture();
            _is_dirty = false;
        }
        return reinterpret_cast<ImTextureID>(_id);
    }

  private:
    void update_texture();
};

} // namespace ciallo